package model.Utils;

import java.security.InvalidParameterException;
import java.util.ArrayList;

import model.FileVO;
import model.Vertex3f;

public class FilesPlacer {
	
	private int mainRing = 6;//number of files on main circle
	private float radius = 2F; // radius of rings
	
	private ArrayList<FileVO> childElements;
	
	public void setNumberOnCircle(int numberOnMainCircle) {
		if (numberOnMainCircle == 0) {
			throw new InvalidParameterException("Nie moze byc 0 plikow na okregu!");
		}
		
		this.mainRing = numberOnMainCircle;
	}
	
	public void placeFiles(ArrayList<FileVO> childElements, float centerX, float centerY, float centerZ, boolean autoRadius) {
		this.childElements = childElements;
		
		if (autoRadius) {
			setRadius(childElements.size()/50 > 2 ? childElements.size()/50 : 2);
		}
		
		for (int i = 0; i < mainRing && i < childElements.size(); ++i) {
			float currentAngle = i * (360 / mainRing);   		
			float x = getX(centerX, radius, currentAngle); 
			float y = getY(centerY, radius, currentAngle);
			
			childElements.get(i).setPosX(x);
			childElements.get(i).setPosY(y);
			childElements.get(i).setPosZ(centerZ);
			childElements.get(i).setRingId(0);		//mainRing ma id = 0.	
			childElements.get(i).setParentCircleCenter(new Vertex3f(centerX, centerY, centerZ, 0));
		}	
		
		int elementsPerRing = (int)(Math.ceil((double)(childElements.size() - mainRing) / (double)mainRing));
		if (elementsPerRing > 0) {
		if (elementsPerRing <= mainRing) {
			elementsPerRing = mainRing;
		}	
		
			for (int i = 0; i < mainRing; ++i) {
					float currentAngle = i * (360 / mainRing);   		
					float nextRingCenterX = getX(centerX, radius * 3, currentAngle);
					float nextRingCenterY = getY(centerY, radius * 3, currentAngle); 			
					float nextRingCenterZ = centerZ - 1;										//TODO: zmienic?
					placeOuterRing(i + 1, mainRing + i * elementsPerRing, elementsPerRing, nextRingCenterX, nextRingCenterY, nextRingCenterZ, currentAngle);				
			}		
		}
			
	}
	
	private void placeOuterRing(int ringId, int startFrom, int elementsPerRing, float centerX, float centerY, float centerZ, float inAngle) {		
		
		for (int i = startFrom; i < startFrom + elementsPerRing; ++i) {			
			float currentAngle = i * (360 / elementsPerRing) - 180 + inAngle;   		
			float x = getX(centerX, radius, currentAngle); 
			float y = getY(centerY, radius, currentAngle);
			
			if (childElements.size() <= i) return;
			childElements.get(i).setPosX(x);
			childElements.get(i).setPosY(y);
			childElements.get(i).setPosZ(centerZ);
			childElements.get(i).setRingId(ringId);		
			childElements.get(i).setParentCircleCenter(new Vertex3f(centerX, centerY, centerZ, ringId));				
		}
	}	
	
	private float getX(float x, float distance, float angle) {	
		return (float) ((distance * Math.cos(Math.toRadians(angle)) + x));
	}
	
	private float getY(float y, float distance, float angle) {
		return (float) ((distance * Math.sin(Math.toRadians(angle))) + y);
	}

	public void setRadius(float radius) {
		if (radius == 0) {
			throw new InvalidParameterException("promien okregu nie moze byc 0!");
		}
		this.radius = radius;
	}

	public float getRadius() {
		return radius;
	}
}
